﻿using System;
using System.Runtime.Serialization;
using System.Web.UI.WebControls;
using System.Linq.Expressions;
using System.Collections.Specialized;
using Mvc.XForms.Utilities;

namespace Mvc.XForms.UI {
	[DataContract]
	public abstract class SortedList<T> : GridItems<T>, ISortedList<T> {
		// Empty constructor so inherited objects can determine init order
		protected SortedList() { }

		protected SortedList(NameValueCollection collection, string sortExpressionKey, string sortDirectionKey, Expression<Func<T, object>> defaultSort, SortDirection defaultSortDirection)
			: this(collection, sortExpressionKey, sortDirectionKey, defaultSort.Body.ExtractID(), defaultSortDirection) { }

		protected SortedList(NameValueCollection collection, string sortExpressionKey, string sortDirectionKey, string defaultSortExpression, SortDirection defaultSortDirection)
			: this(new SortedParameters(collection, sortExpressionKey, sortDirectionKey, defaultSortExpression, defaultSortDirection)) { }

		protected SortedList(ISortedParameters gridParams) {
			InitWithParams(gridParams);
		}

		protected SortedList(string sortExpression, SortDirection sortDirection) {
			Init(sortExpression, sortDirection);
		}

		protected void InitWithParams(ISortedParameters gridParams) {
			SetParameters(gridParams);
			Init(gridParams.SortExpression, gridParams.SortDirection);
		}

		protected void Init(string sortExpression, SortDirection sortDirection) {
			SortExpression = sortExpression;
			SortDirection = sortDirection;

			ApplySorting();
		}

		public void SetParameters(ISortedParameters gridParams) {
			SortExpressionKey = gridParams.SortExpressionKey;
			SortDirectionKey = gridParams.SortDirectionKey;
		}

		protected abstract void ApplySorting();

		[DataMember]
		public string SortExpression { get; set; }
		[DataMember]
		public SortDirection SortDirection { get; set; }
		[DataMember]
		public string SortExpressionKey { get; protected set; }
		[DataMember]
		public string SortDirectionKey { get; protected set; }
	}
}